#! /usr/bin/env python

## @package drawtracker2
# Package for drawing a two-layer tracker.
# @version 1.0
#
# Usage: %prog
#
# @todo Make configurable with command line options.
# @todo Make the minimum thickness replacement universal.


import os
import tempfile
import shutil
from math import *

## Writes the header of a pspicture LaTeX document.
#
def writeheader(paperheight,aspectratio,xoffset,yoffset):
    paperwidth = paperheight * aspectratio
    out = ""
    out += "\\documentclass{article}\n"
    out += "\\usepackage{pstricks}\n"
    out += "\\usepackage{pst-all}\n"
    out += "\\selectcolormodel{rgb}\n"
#%%\usepackage{amsmath}
#%%\usepackage{amssymb}
#%%\usepackage{relsize}
    out += "\\usepackage{pspicture}\n"
    out += "\\usepackage[dvips,paperwidth=%10.5fcm,paperheight=%10.5fcm,\n" % (paperwidth,paperheight)
    out += "left=0cm,right=0cm,top=0cm,bottom=0cm,headheight=0pt,headsep=0pt,footskip=0pt,\n"
#%		out += ('  left=%4.3fcm, right=0cm,\n' %(inputdata.description['LeftMargin']-0.45,))
#%		out += ('  top=%4.3fcm,  bottom=0cm,\n' %(inputdata.description['TopMargin']-0.30,))
#%		out += ('  paperwidth=%scm,paperheight=%scm\n' %(papersizex,papersizey))
    out += "]{geometry}\n"
    out += "\\oddsidemargin=-1in\n"
    out += "\\topmargin=-1in\n"
    out += "\\parindent=0pt\n"
    out += "\\begin{document}\n"
    out += "\\pagestyle{empty}\n"
    out += "\\SpecialCoor\n"
    out += "\\setlength{\unitlength}{1.0cm}\n"
    out += "\\begin{pspicture}(0,0)(-%10.5f,%10.5f)\n" % (xoffset,paperheight-yoffset)
    out += "\\linethickness{0.8pt}\n"
    return out 

## Writes the footer for a pspicture LaTeX file.
#
def writefooter():
    out = ""
    out += "\\end{pspicture}\n"
    out += "\\end{document}\n"
    return out

def drawtrack(C,phi,d,cutoff):
    out = ''
    phi_deg = (180./pi)*phi
    R = 1./C
    x = -1.0 * R * sin(phi)
    y =        R * cos(phi)
    addedphi_deg = 2.*(180./pi)*(asin(cutoff/(2.*R)))
    #out += '\\pscircle[linewidth=0.3pt](%10.5f,%10.5f){%10.5f}\n' % (x,y,R)
    out += '\\psarc[linewidth=0.3pt,linestyle=dashed,dash=1.5pt 0.75pt](%10.5f,%10.5f){%10.5f}{%10.5f}{%10.5f}\n' % (x,y,R,phi_deg-90.,phi_deg-90.+addedphi_deg)
    return out

def drawinteractionpoint(x,y):
    out = ''
    out += '\\pscircle[fillstyle=solid,linewidth=0.3pt,fillcolor=white](%10.5f,%10.5f){0.05}\n' % (x,y)
    return out

def drawhit(rho,phi):
    out = ''
    out += '\\pscircle[fillstyle=solid,linewidth=0.3pt,fillcolor=white](%10.5f;%10.5f){0.03}\n' % (rho,phi)
    return out

def drawxaxis(length):
    out = ''
    #out += '\\psline[linewidth=0.3pt,arrowsize=4pt 3,arrowinset=0.4]{->}(0.0,0.0)(%10.5f;0.0)\n' % (length)
    out += '\\psline[linewidth=0.3pt,arrowinset=0.4]{->}(0.0,0.0)(%10.5f;0.0)\n' % (length)
    out += '\\uput{0.14}[-10.](%5.2f,%5.2f){\\scriptsize $x$}\n' % (length,0.0)
    return out

def drawmagfield(x,y,rad):
    out = ''
    out += '\\pscircle[linewidth=0.3pt](%10.5f,%10.5f){%10.5f}\n' % (x,y,rad)
    out += '\\uput{%10.5f}[0.0](%10.5f,%10.5f){\\scriptsize $B$}\n' % (rad+0.1,x,y)
    out += '\\psline[linewidth=0.3pt](%10.5f,%10.5f)(%10.5f,%10.5f)\n' % (x,y,x+rad/sqrt(2.),y+rad/sqrt(2.))
    out += '\\psline[linewidth=0.3pt](%10.5f,%10.5f)(%10.5f,%10.5f)\n' % (x,y,x-rad/sqrt(2.),y+rad/sqrt(2.))
    out += '\\psline[linewidth=0.3pt](%10.5f,%10.5f)(%10.5f,%10.5f)\n' % (x,y,x+rad/sqrt(2.),y-rad/sqrt(2.))
    out += '\\psline[linewidth=0.3pt](%10.5f,%10.5f)(%10.5f,%10.5f)\n' % (x,y,x-rad/sqrt(2.),y-rad/sqrt(2.))
    return out


## Desired height of the figure (cm)
figheight = 4.0

## Desired aspect ratio of the figure
#asprat = 1.33333333
asprat = 1.9

## Base names of the files produced by the script.
filename = 'fig3'
#texfilename = filename + '.tex'

## Current working directory.
cwd = os.getcwd()
## Temporary directory for files used in figure construction.
tempdir = tempfile.mkdtemp('.drawtracker')
## Path to the .tex file.
texpath = os.path.join(tempdir, filename+'.tex')

## The Tex file to which the figure is written.
texfile = open(texpath,'w')

## The ratio of the tracker radius to the figure height
rho2_over_figheight = 1.5
rho2 = rho2_over_figheight*figheight
rho1_over_rho2 = 0.5
rho1 = rho1_over_rho2 * rho2
rho_cutoff = rho2 + 0.2

# The hits
N_phi_det = 64.
Delta_phi_deg = (360./N_phi_det)
phi1_deg = 54. * Delta_phi_deg
phi1 = (pi*phi1_deg)/180.
phi2_deg = 62. * Delta_phi_deg
phi2 = (pi*phi2_deg)/180.
x1 = rho1*cos(phi1)
y1 = rho1*sin(phi1)
x2 = rho2*cos(phi2)
y2 = rho2*sin(phi2)
xmid = x1+(x2-x1)/2.
ymid = y1+(y2-y1)/2.


# Find the track
R_track = sqrt(rho1*rho1 + rho2*rho2 - 2.*rho1*rho2*cos(phi2 - phi1))
R_track /= (2.*sin(phi2 - phi1))
theta = acos(rho2/(2.*R_track))
phi_track = phi1 - (pi/2. - (phi2-phi1) - theta)
phi_track_deg = (180./pi)*phi_track

## The vertical offset of the origin on the page.
#centre_offset = ((1.0 - rho2_over_figheight)/2.0) * figheight
#centre_offset = 0.8 * figheight
xoffset = 0.2 * figheight
yoffset = 0.85 * figheight
#centre_offset = 0.5 * figheight

# Write the LaTeX document header.
texfile.write(writeheader(figheight,asprat,xoffset,yoffset))

# cutoff
texfile.write('\\pscircle[linewidth=0.3pt,fillstyle=solid,fillcolor=lightgray](0.0,0.0){%10.5f}\n' % (rho_cutoff+4.0))
texfile.write('\\pscircle[linewidth=0.3pt,fillstyle=solid,fillcolor=white](0.0,0.0){%10.5f}\n' % (rho_cutoff))

# Draw tracker layers - N_det -> inf.
texfile.write('\\pscircle[linewidth=0.3pt](0.0,0.0){%10.5f}\n' % rho2)
texfile.write('\\pscircle[linewidth=0.3pt](0.0,0.0){%10.5f}\n' % (rho2+0.04))
texfile.write('\\pscircle[linewidth=0.3pt](0.0,0.0){%10.5f}\n' % rho1)
texfile.write('\\pscircle[linewidth=0.3pt](0.0,0.0){%10.5f}\n' % (rho1+0.04))

# Draw track(s)
texfile.write(drawtrack(1./R_track,phi_track,0.0,rho_cutoff))
p_track = 1.5
texfile.write('\\psline[linewidth=0.5pt]{->}(0.0,0.0)(%10.5f;%10.5f)\n' % (p_track,phi_track_deg))
# Label track
texfile.write('\\uput{0.15}[180](%10.5f;%10.5f){\\scriptsize $\\mathbf{p}_{\\mathrm{trk}}$}\n' % (p_track,phi_track_deg))
# phi_track label
texfile.write('\\psarc[linewidth=0.3pt]{->}(0.0,0.0){%10.5f}{%10.5f}{%10.5f}\n' % (0.2,0.0,phi_track_deg))
texfile.write('\\uput{0.1}[%10.5f](%10.5f;%10.5f){\\scriptsize $\\phi_{\mathrm{trk}}$}\n' % (phi_track_deg/2.,0.2,phi_track_deg/2.))
# Draw circumcentre
texfile.write('\\pscircle*(%10.5f;%10.5f){0.03}\n' % (R_track,phi_track_deg+90.))
# Draw circumcircle radii
texfile.write('\\psline[linewidth=0.3pt,linestyle=dashed,dash=1.5pt 0.75pt](0.0,0.0)(%10.5f;%10.5f)\n' % (R_track,phi_track_deg+90.))
texfile.write('\\psline[linewidth=0.3pt,linestyle=dashed,dash=1.5pt 0.75pt](%10.5f;%10.5f)(%10.5f;%10.5f)\n' % (R_track,phi_track_deg+90.,rho2,phi2_deg))
# Label them
circumx = R_track*cos(phi_track+pi/2.)
circumy = R_track*sin(phi_track+pi/2.)
texfile.write('\\uput{0.15}[%10.5f](%10.5f;%10.5f){\\scriptsize $R_{\\mathrm{trk}}$}\n' % (phi_track_deg+180.,R_track/2.,phi_track_deg+90.))
texfile.write('\\uput{0.15}[%10.5f](%10.5f,%10.5f){\\scriptsize $R_{\\mathrm{trk}}$}\n' % (phi_track_deg+90.+(360./pi)*asin(R_track/rho2),circumx+(x2-circumx)/2.,circumy+(y2-circumy)/2.))


# Label the hits with position vectors
texfile.write('\\psline[linewidth=0.3pt,arrowinset=0.0]{->}(0.0,0.0)(%10.5f;%10.5f)\n' % (rho1/2.,phi1_deg))
texfile.write('\\psline[linewidth=0.3pt](%10.5f;%10.5f)(%10.5f;%10.5f)\n' % (rho1/2.-0.05,phi1_deg,rho1,phi1_deg))
texfile.write('\\psline[linewidth=0.3pt,arrowinset=0.0]{->}(0.0,0.0)(%10.5f;%10.5f)\n' % (rho2/2.,phi2_deg))
texfile.write('\\psline[linewidth=0.3pt](%10.5f;%10.5f)(%10.5f;%10.5f)\n' % (rho2/2.-0.05,phi2_deg,rho2,phi2_deg))
texfile.write('\\psline[linewidth=0.3pt,arrowinset=0.0]{->}(%10.5f,%10.5f)(%10.5f,%10.5f)\n' % (x1,y1,xmid,ymid))
texfile.write('\\psline[linewidth=0.3pt]{c-}(%10.5f,%10.5f)(%10.5f,%10.5f)\n' % (x1+(x2-x1)/2.1,y1+(y2-y1)/2.1,x2,y2))
#texfile.write('\\psline[linewidth=0.3pt](%10.5f;%10.5f)(%10.5f;%10.5f)\n' % (rho2/2.,phi2_deg,rho2,phi2_deg))
# Label the position vectors
texfile.write('\\uput{0.1}[%10.5f](%10.5f;%10.5f){\\scriptsize $\\mathbf{r}_{1}=(\\rho_{1}; \\phi_{1})$}\n' % (phi1_deg+90.,rho1/2.+0.1,phi1_deg))
texfile.write('\\uput{0.2}[%10.5f](%10.5f;%10.5f){\\scriptsize $\\mathbf{r}_{2}=(\\rho_{2}; \\phi_{2})$}\n' % (phi2_deg-90.,2.9*rho2/4.,phi2_deg))
angle = (180./pi)*atan2(y2-y1,x2-x1)
texfile.write('\\uput{0.15}[%10.5f](%10.5f,%10.5f){\\scriptsize $\\mathbf{r}_{2} - \\mathbf{r}_{1}$}\n' % (angle-90.,xmid,ymid))
#
# Phi (difference) label
texfile.write('\\psarc[linewidth=0.3pt]{->}(0.0,0.0){%10.5f}{%10.5f}{%10.5f}\n' % (0.7,phi1_deg,phi2_deg))
philabel = (0.5 * (phi2_deg-phi1_deg)) + phi1_deg
texfile.write('\\uput{0.1}[%10.5f](%10.5f;%10.5f){\\scriptsize %s}\n' % (philabel,0.7,philabel,'$\\phi_{2} - \\phi_{1}$'))

# Draw hits
texfile.write(drawhit(rho1,phi1_deg))
texfile.write(drawhit(rho2,phi2_deg))

# Draw x axis
texfile.write(drawxaxis(1.0))

texfile.write(drawmagfield(0.0,-2.5,0.1))

# Draw the interaction point
texfile.write(drawinteractionpoint(0.0,0.0))

# Write the LaTeX document footer.
texfile.write(writefooter())
# Close the LaTeX file.
texfile.close()


#Make the PDF from the latex.
import subprocess

#run LaTeX on the generated figure LaTeX file.
#print texpath
#texcmd = ["latex", texpath]

## Process for running the LaTeX figure generation.
texproc = subprocess.Popen(["latex", texpath], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=tempdir)
texproc.wait()

## Process for running the dvi to ps conversion.
dvproc = subprocess.Popen(["dvips", os.path.join(tempdir,filename+".dvi")], stdout=subprocess.PIPE, cwd=tempdir)
dvproc.wait()

## Process for running the ps to pdf conversion.
cnvproc = subprocess.Popen(["ps2pdf", os.path.join(tempdir,filename+".ps")], stdout=subprocess.PIPE, cwd=tempdir)
cnvproc.wait()

## The output path for the final PDF.
outpath = os.path.join(tempdir, filename+".pdf")
if os.path.exists(outpath):
    shutil.copy(outpath, cwd)
## The output path for the final .tex file (for debugging).
outtex = os.path.join(tempdir, filename+".tex")
if os.path.exists(outtex):
    shutil.copy(outtex, cwd)

shutil.rmtree(tempdir, ignore_errors=True) # delete the temporary files
